package org.jeecg.modules.data.util;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.jeecg.modules.data.entity.DisExcelData;
import org.jeecg.modules.data.entity.TDataReport;
import org.jeecg.modules.data.entity.TDataStatistics;

import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class FileUtils {

    /**
     * 生成word文件并上传
     * @param templateAreaFile
     * @param statistics
     * @param report
     */
    public static void createWordFile(String templateAreaFile, String filePath, String fileName, TDataStatistics statistics, List<TDataReport> report) {
        InputStream ins = null;
        OutputStream out = null;
        try {
            // Step.1、判断模板文件是否存在
            File templateFile = new File(templateAreaFile);
            if (!templateFile.exists()){
                throw new IOException("模板文件不存在:" + templateAreaFile);
            }
            //获取Word模板，模板存放路径
            ins = new FileInputStream(templateFile);
            //注册xdocreport实例并加载FreeMarker模板引擎
            IXDocReport docReport = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);
            //创建xdocreport上下文对象，用于存放具体数据
            IContext context = docReport.createContext();
            //创建要替换的文本变量
            TDataReport tDataReport = new TDataReport();
            tDataReport.setInvestigationId(statistics.getInvestigationId());
            tDataReport.setCantCode(statistics.getCantCode());
            context.put("report", report);

            // 非列表字段
            context.put("title", getTitile(statistics.getName()));
            context.put("realname", statistics.getRealname());
            context.put("phone", statistics.getPhone());
            context.put("townCount", statistics.getTownCount());
            context.put("samplingPointCount", statistics.getSamplingPointCount());
            context.put("averageLossRate", statistics.getAverageLossRate());
            //创建字段元数据
            FieldsMetadata fm = docReport.createFieldsMetadata();
            //Word模板中的表格数据对应的集合类型
            fm.load("report", TDataReport.class, true);
            //输出到目录
            File file = new File(filePath);
            if (!file.exists()) {
                // 创建文件根目录
                file.mkdirs();
            }
            out = new FileOutputStream(filePath + fileName);
            docReport.process(context, out);
        } catch (Exception e) {
            System.out.println("生成word发生异常"+e);
        }finally {
            try {
                if (ins != null){
                    ins.close();
                }
            } catch (IOException e) {
                System.out.println("文件流关闭失败"+e);
            }
        }
    }

    public static void createExcelFile(String excelTempFile, String filePath, String fileName, TDataStatistics statistics, List<DisExcelData> reports, String reportDate) {
        InputStream ins = null;
        try {
            // Step.1、判断模板文件是否存在
            File templateFile = new File(excelTempFile);
            if (!templateFile.exists()){
                throw new IOException("模板文件不存在:" + excelTempFile);
            }
            //获取Excel模板，模板存放路径
            ins = new FileInputStream(templateFile);
            File file = new File(filePath);
            if (!file.exists()) {
                // 创建文件根目录
                file.mkdirs();
            }
            File excelFile = new File(filePath + fileName);

            String sheelname = getType(statistics.getName());
            //需要合并的列
            int[] mergeColumeIndex = {0, 1, 2, 3, 4};
            //需要从第一行开始，列头第一行
            int mergeRowIndex = 1;
            GroupedMergeStrategy mergeIdStrategy = new GroupedMergeStrategy(mergeRowIndex, mergeColumeIndex);

            ExcelWriter excelWriter = EasyExcel.write(excelFile)
                    .withTemplate(ins)
                    .registerWriteHandler(mergeIdStrategy)
                    .registerWriteHandler(cellBorder())
                    .build();

            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

            Map<String, Object> map = new HashMap<>();
            map.put("title", getTitile(statistics.getName()));
            map.put("reportDate", reportDate);
            excelWriter.fill(map, writeSheet);

            excelWriter.fill(new FillWrapper("report", reports), fillConfig, writeSheet);
            excelWriter.finish();
            ins.close();
        } catch (Exception e) {
            System.out.println("生成excel发生异常"+e);
        }finally {
            try {
                if (ins != null){
                    ins.close();
                }
            } catch (IOException e) {
                System.out.println("文件流关闭失败"+e);
            }
        }
    }

    /**
     * 获取导出标题
     * @param input
     * @return
     */
    public static String getTitile(String input) {
        Pattern pattern = Pattern.compile("【(.*?)】\\d{4}年\\s*(\\p{L}+)");
        Matcher matcher = pattern.matcher(input);
        if (matcher.find()) {
            return matcher.group(1) + matcher.group(2);
        }
        return null;
    }

    /**
     * 获取导出类型
     * @param input
     * @return
     */
    public static String getType(String input) {
        Pattern pattern = Pattern.compile("【(.*?)】\\d{4}年\\s*(\\p{L}+)");
        Matcher matcher = pattern.matcher(input);
        if (matcher.find()) {
            return matcher.group(2);
        }
        return null;
    }

    /**
     * 生成随机数
     * @return
     */
    public static String generateRandomNumber() {
        // 获取当前日期并格式化
        String datePart = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);

        // 生成四位随机数（0000-9999）
        int randomNumber = ThreadLocalRandom.current().nextInt(10000);
        String randomPart = String.format("%04d", randomNumber);

        // 组合最终结果
        return datePart + randomPart;
    }

    public static void main(String[] args) {
        try {
            String reportDate = DateUtil.date().toString("yyyy年MM月dd日");
            File templateFile = new File("jeecg-boot-module-system/src/main/resources/templates/summary.xlsx");
            if (!templateFile.exists()) {
                throw new IOException("模板文件不存在");
            }
            InputStream templateStream = new FileInputStream(templateFile);
            String resultFileName = "汇总.xlsx";
            File file = new File("D://temp//" + resultFileName);
            List<DisExcelData> list = hisData();

            // 确保数据按序号（第一列）排序
            // 假设DisExcelData有getNum()方法获取序号
            list.sort(Comparator.comparing(DisExcelData::getCityno));

            //需要合并的列
            int[] mergeColumeIndex = {0, 1, 2, 3, 4};
            //需要从第一行开始，列头第一行
            int mergeRowIndex = 1;
            GroupedMergeStrategy mergeIdStrategy = new GroupedMergeStrategy(mergeRowIndex, mergeColumeIndex);

            ExcelWriter excelWriter = EasyExcel.write(file)
                    .withTemplate(templateStream)
                    .registerWriteHandler(mergeIdStrategy)
                    .registerWriteHandler(cellBorder())
                    .build();

            WriteSheet writeSheet = EasyExcel.writerSheet().build(); // 0表示第一个Sheet

            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

            excelWriter.fill(new FillWrapper("report", list), fillConfig, writeSheet);
            Map<String, Object> map = new HashMap<>();
            map.put("title", "青岛市大豆");
            map.put("reportDate", reportDate);
            excelWriter.fill(map, writeSheet);
            excelWriter.finish();
            templateStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static HorizontalCellStyleStrategy cellBorder(){
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        return new HorizontalCellStyleStrategy(contentWriteCellStyle, contentWriteCellStyle);
    }

    private static List<DisExcelData> hisData() {
        List<DisExcelData> list = new ArrayList<>();
        DisExcelData data = new DisExcelData();
        data.setCityno(1);
        data.setCantName("青岛市");
        data.setTownCount(22);
        data.setSamplingPointCount(23);
        data.setAverageLossRate(BigDecimal.valueOf(4.52));
        list.add(data);
        DisExcelData data2 = new DisExcelData();
        data2.setCityno(1);
        data2.setCantName("黄岛区");
        data2.setTownCount(4);
        data2.setSamplingPointCount(4);
        data2.setAverageLossRate(BigDecimal.valueOf(4.41));
        data2.setAreano(1);
        data2.setSamplingDateStr("2024-10-20");
        data2.setSamplingLocation("六汪镇崔戈庄");
        data2.setLossAmount(BigDecimal.valueOf(4.37));
        data2.setUnitAreaYield(BigDecimal.valueOf(0.33));
        data2.setLossRate(BigDecimal.valueOf(4.48));
        list.add(data2);
        DisExcelData dataQingdaoQuSample2 = new DisExcelData();
        dataQingdaoQuSample2.setCityno(1);
        dataQingdaoQuSample2.setCantName("黄岛区");
        dataQingdaoQuSample2.setTownCount(4);
        dataQingdaoQuSample2.setSamplingPointCount(4);
        dataQingdaoQuSample2.setAverageLossRate(BigDecimal.valueOf(4.41));
        dataQingdaoQuSample2.setAreano(2);
        dataQingdaoQuSample2.setSamplingDateStr("2024-10-20");
        dataQingdaoQuSample2.setSamplingLocation("泊里菜园村");
        dataQingdaoQuSample2.setLossAmount(BigDecimal.valueOf(1.94));
        dataQingdaoQuSample2.setUnitAreaYield(BigDecimal.valueOf(0.15));
        dataQingdaoQuSample2.setLossRate(BigDecimal.valueOf(4.45));
        list.add(dataQingdaoQuSample2);
        DisExcelData dataQingdaoQuSample3 = new DisExcelData();
        dataQingdaoQuSample3.setCityno(1);
        dataQingdaoQuSample3.setCantName("黄岛区");
        dataQingdaoQuSample3.setTownCount(4);
        dataQingdaoQuSample3.setSamplingPointCount(4);
        dataQingdaoQuSample3.setAverageLossRate(BigDecimal.valueOf(4.41));
        dataQingdaoQuSample3.setAreano(3);
        dataQingdaoQuSample3.setSamplingDateStr("2024-10-20");
        dataQingdaoQuSample3.setSamplingLocation("大场镇侯子埠村");
        dataQingdaoQuSample3.setLossAmount(BigDecimal.valueOf(4.22));
        dataQingdaoQuSample3.setUnitAreaYield(BigDecimal.valueOf(0.33));
        dataQingdaoQuSample3.setLossRate(BigDecimal.valueOf(4.3));
        list.add(dataQingdaoQuSample3);
        DisExcelData dataQingdaoQuSample4 = new DisExcelData();
        dataQingdaoQuSample4.setCityno(1);
        dataQingdaoQuSample4.setCantName("黄岛区");
        dataQingdaoQuSample4.setTownCount(4);
        dataQingdaoQuSample4.setSamplingPointCount(4);
        dataQingdaoQuSample4.setAverageLossRate(BigDecimal.valueOf(4.41));
        dataQingdaoQuSample4.setAreano(4);
        dataQingdaoQuSample4.setSamplingDateStr("2024-10-20");
        dataQingdaoQuSample4.setSamplingLocation("大村镇西南庄村");
        dataQingdaoQuSample4.setLossAmount(BigDecimal.valueOf(3.37));
        dataQingdaoQuSample4.setUnitAreaYield(BigDecimal.valueOf(0.26));
        dataQingdaoQuSample4.setLossRate(BigDecimal.valueOf(4.4));
        list.add(dataQingdaoQuSample4);
        DisExcelData dataQingdaoQu = new DisExcelData();
        dataQingdaoQu.setCityno(1);
        dataQingdaoQu.setCantName("胶州市");
        dataQingdaoQu.setTownCount(4);
        dataQingdaoQu.setSamplingPointCount(5);
        dataQingdaoQu.setAverageLossRate(BigDecimal.valueOf(3.8));
        dataQingdaoQu.setAreano(1);
        dataQingdaoQu.setSamplingDateStr("2024-10-20");
        dataQingdaoQu.setSamplingLocation("铺集鹿家");
        dataQingdaoQu.setLossAmount(BigDecimal.valueOf(15));
        dataQingdaoQu.setUnitAreaYield(BigDecimal.valueOf(210));
        dataQingdaoQu.setLossRate(BigDecimal.valueOf(2.38));
        list.add(dataQingdaoQu); // 先加区级数据，再加采样点
        return list;
    }
}
